mod config;
mod ly1010_otp;

use config::*;


// // N: total bits number.
// struct OTPdata<'a, const N: usize>(IndexMap<&'a str, Segment<'a>>);

// struct Segment<'a> {
//     value: SegValue,
//     start: u16,
//     width: u16,
//     readonly: bool,
//     description: &'a str
// }

// enum SegValue {
//     U8(u8),
//     U16(u16),
//     U32(u32),
//     U128(u128),
//     I8(i8),
//     I16(i16),
//     I32(i32),
//     I128(i128),
//     Bool(bool),
//     Bin(String),
//     Bytes(Vec<u8>),
// }


// enum OtpSegments {
//     // type, name, literal(closure), minimum, maximum, default, description
//     Flag{
//         val: bool,
//         literal: Box<dyn Fn(bool)->String>,
//         range: std::ops::RangeInclusive<bool>,
//         occupied: (u16, u16),
//         default: bool,
//         desc: String},
//     U8{
//         val: u8,
//         literal: Box<dyn Fn(u8)->String>,
//         range: std::ops::RangeInclusive<i8>,
//         occupied: (usize, usize),
//         default: u8,
//         desc: String},
//     U16{
//         val: u16,
//         literal: Box<dyn Fn(u16)->String>,
//         range: std::ops::RangeInclusive<i8>,
//         occupied: (usize, usize),
//         default: u16,
//         desc: String},
//     U32{
//         val: u32,
//         literal: Box<dyn Fn(u32)->String>,
//         range: std::ops::RangeInclusive<i8>,
//         occupied: (usize, usize),
//         default: u32,
//         desc: String},
//     U64{
//         val: u64,
//         literal: Box<dyn Fn(u64)->String>,
//         range: std::ops::RangeInclusive<i8>,
//         occupied: (usize, usize),
//         default: u64,
//         desc: String},
//     U128{
//         val: u128,
//         literal: Box<dyn Fn(u128)->String>,
//         range: std::ops::RangeInclusive<i8>,
//         occupied: (usize, usize),
//         default: u128,
//         desc: String},
//     I8{
//         val: i8,
//         literal: Box<dyn Fn(i8)->String>,
//         range: std::ops::RangeInclusive<i8>,
//         occupied: (usize, usize),
//         default: i8,
//         desc: String},
// }


// impl<'a, const N:usize> std::ops::Deref for OTPdata<'a, N> {
//     type Target = IndexMap<&'a str, Segment<'a>>;

//     fn deref(&self) -> &Self::Target {
//         &self.0
//     }
// }


// impl <'a, const N:usize> std::ops::DerefMut for OTPdata<'a, N> {
//     fn deref_mut(&mut self) -> &mut Self::Target {
//         &mut self.0
//     }
// }



// impl <'a, const N:usize> OTPdata<'a, N> {
//     fn from<'b>(input: [(&'b str, (SegValue, u16, bool, &'b str)); N]) -> Self {
//         let mut data = [0u8; N];
//         let mut meta = IndexMap::<&'a str, Segment<'a>>::new();
//         let mut start = 0u16;
//         for (key, (val, wid, ro, desc)) in input {
//             match val {
//                 SegValue::U8(v) => {
//                     assert!(wid <= 8, "Width too wide for u8!!!");
//                     if start % 8 + wid <= 8 {
//                         data[(start/8) as usize] |= (v&((-1i8 as u8)>>(8-wid)))<<(start%8);
//                     } else if start % 8 + wid <= 16{
//                         data[(start/8) as usize] |= (v&((-1i8 as u8)>>(8-wid)))<<(start%8);
//                         data[((start/8)+1) as usize] |= (v&(u8::MAX>>(8-wid)))>>(8-(start%8));
//                     } else {
//                         panic!("Segment widths error:[{wid}]");
//                     }
//                 },
//                 SegValue::U16(v) => {

//                 },
//                 _ => panic!("Invalid value type"),
//             }
//             meta.insert(key, (val, start, ro, desc));
//             start += wid;
//         }
//         Self {
//             data: [0; N],
//             meta
//         }
//     }
// }




fn main() {
    let seg = SegmentType::Flag { val: true, literal: Box::new(|x:bool| x.to_string()),  range: false..=true, occupied: (0,1), lsb0:true, default: false, desc: "Parity bit" };
    println!("{:?}", seg);
    let seg = SegmentType::U32 { val: 345, literal: Box::new(|x| (x+1).to_string()), range: 0..=2047, occupied: (1,8), lsb0:true, default: 0, desc: "PCBATTNA" };
    println!("{:?}", seg);
    // println!("{:?}", m);
    // println!("{:?}", m.get("b"));
    // println!("{:?}", m.get_index(2));
}

